from django.shortcuts import render
from django.views.generic import View
from utils.views import LoginRequiredJSONMixin
from django.http import JsonResponse, HttpResponseForbidden
from django.db import DataError
import json
from .models import OrderInfo, Payment
from django.utils import timezone
from alipay import AliPay
from django.conf import settings
import os


# Create your views here.
class PaymentView(LoginRequiredJSONMixin, View):
    def post(self, request):
        """get alipay code api"""
        # get params
        params_str = request.body.decode()
        # check params
        if not params_str:
            return JsonResponse({'code': 4001, 'errormsg': 'params is not enough!!'})

        params_dict = json.loads(params_str)
        pay_method = params_dict['pay_method']
        total_amount = params_dict['pay_amount']
        article_id = params_dict['article_id']

        user = request.user
        # generate order_id
        order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%03d' % user.id)

        # generate pay_order
        try:
            order = OrderInfo.objects.create(order_id=order_id, user=user, total_amount=total_amount, pay_method=pay_method, article_id=article_id)
        except DataError:
            return JsonResponse({'code': 4002, 'errormsg': '生成订单失败！！'})

        # get url
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,
            app_private_key_string=open(
                os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")
            ).read(),
            alipay_public_key_string=open(
                os.path.join((os.path.dirname(os.path.abspath(__file__))), "keys/alipay_public_key.pem")
            ).read(),
            sign_type="RSA2",
            debug=settings.ALIPAY_DEBUG
        )

        # ⽣成登录⽀付宝连接
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,
            total_amount=str(order.total_amount),
            subject="芒果头条%s" % order_id,
            return_url=settings.ALIPAY_RETURN_URL,
            notify_url=settings.ALIPAY_RETURN_URL
        )
        # 响应登录⽀付宝链接
        # 真实环境电脑⽹站⽀付⽹关：https://openapi.alipay.com/gateway.do?+order_string
        # 沙箱环境电脑⽹站⽀付⽹关：https://openapi.alipaydev.com/gateway.do?+order_string
        alipay_url = settings.ALIPAY_URL + "?" + order_string
        # return params
        return JsonResponse({'code': 200, 'errormsg': 'OK', 'alipay_url': alipay_url})


class PaymentStatusView(LoginRequiredJSONMixin, View):
    def get(self, request):
        """
        查询并保存支付结果
        :param request:
        :return:
        """
        # get params
        params_dict = request.GET.dict()

        # check params(Judge whether the request is forwarded by Alipay)
        sign = params_dict.pop('sign')

        # new a AliPay Object
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,
            app_private_key_string=open(
                os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")
            ).read(),
            alipay_public_key_string=open(
                os.path.join((os.path.dirname(os.path.abspath(__file__))), "keys/alipay_public_key.pem")
            ).read(),
            sign_type="RSA2",
            debug=settings.ALIPAY_DEBUG
        )

        flag = alipay.verify(params_dict, sign)

        #
        if flag:  # legal order
            # get order_id
            order_id = params_dict.get('out_trade_no')

            # get trade_id
            trade_id = params_dict.get('trade_no')

            try:
                Payment.objects.create(order_id=order_id, trade_id=trade_id)
            except DataError:
                return HttpResponseForbidden('保存支付结果失败!!')

            # Update database order table status
            OrderInfo.objects.filter(order_id=order_id, status=1).update(status=2)

            # Response page results
            return render(request, 'payment/pay_success.html', {'trade_id': trade_id})

        else:  # illegal order
            return HttpResponseForbidden('非正常请求订单!!')
